<?php

namespace app\common\service;

use app\common\controller\Send;
use OSS\OssClient;
use OSS\Core\OssUtil;
use OSS\Core\OssException;
class Oss
{
    use Send;

    protected $accessKeyId;
    protected $accessKeySecret;
    protected $endpoint;
    // 存储空间名称
    protected $bucket;
    public function __construct()
    {
//        $config = [
//            'access_key_id' => '12',
//            'access_key_secret' => '34',
//            'endpoint' => '22',
//            'bucket' => 'testtest'
//        ];
        $config = config('app.aliyun_oss');
        $this->accessKeyId = $config['access_key_id'];
        $this->accessKeySecret = $config['access_key_secret'];
        $this->endpoint = $config['endpoint'];
        $this->admin_endpoint = $config['admin_endpoint'];
        $this->bucket = $config['bucket'];
    }

    /**
     * 上传字符串到OSS
     * @param string $object 文件名称
     * @param string $content 文件内容
     * @param null $options
     * @return array
     */
    public function put($object, $content, $options = NULL)
    {
        try {
            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $ossClient->putObject($this->bucket, $object, $content, $options);
            return self::sendResult(self::$okCode);
        } catch (\Exception $e) {
            return self::sendResult(128, $e->getMessage());
        }
    }

    /**
     * 上传文件到oss
     * @param string $object 文件名称
     * @param string $file <yourLocalFile>由本地文件路径加文件名包括后缀组成，例如/users/local/myfile.txt
     * @param null $options
     * @return array
     */
//    public function upload($object, $file, $options = NULL)
//    {
//        try {
//            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
//            $ossClient->uploadFile($this->bucket, $object, $file, $options);
//            return self::sendResult(self::$okCode);
//        } catch (\Exception $e) {
//            return self::sendResult(128, $e->getMessage());
//        }
//    }
    public function upload($object, $file, $options = NULL)
    {
        try {


            $ossClient = new OssClient($this->accessKeyId, $this->accessKeySecret, $this->endpoint);
            $uploadId = $ossClient->initiateMultipartUpload($this->bucket, $object, $options);
            $partSize = 10 * 1024 * 1024;

            $uploadFileSize = filesize($file);

            $pieces = $ossClient->generateMultiuploadParts($uploadFileSize, $partSize);
            $responseUploadPart = array();
            $uploadPosition = 0;
            $isCheckMd5 = true;
            foreach ($pieces as $i => $piece) {
                $fromPos = $uploadPosition + (integer)$piece[$ossClient::OSS_SEEK_TO];
                $toPos = (integer)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1;
                $upOptions = array(
                    // 上传文件。
                    $ossClient::OSS_FILE_UPLOAD => $file,
                    // 设置分片号。
                    $ossClient::OSS_PART_NUM => ($i + 1),
                    // 指定分片上传起始位置。
                    $ossClient::OSS_SEEK_TO => $fromPos,
                    // 指定文件长度。
                    $ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
                    // 是否开启MD5校验，true为开启。
                    $ossClient::OSS_CHECK_MD5 => $isCheckMd5,
                );
                // 开启MD5校验。
                if ($isCheckMd5) {
                    $contentMd5 = OssUtil::getMd5SumForFile($file, $fromPos, $toPos);
                    $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
                }
                try {
                    // 上传分片。
                    $responseUploadPart[] = $ossClient->uploadPart($this->bucket, $object, $uploadId, $upOptions);
                } catch(OssException $e) {
//                    printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} FAILED\n");
//                    printf($e->getMessage() . "\n");
                    return;
                }
//                printf(__FUNCTION__ . ": initiateMultipartUpload, uploadPart - part#{$i} OK\n");
            }
            $uploadParts = array();
            foreach ($responseUploadPart as $i => $eTag) {
                $uploadParts[] = array(
                    'PartNumber' => ($i + 1),
                    'ETag' => $eTag,
                );
            }
            try {
                // 执行completeMultipartUpload操作时，需要提供所有有效的$uploadParts。OSS收到提交的$uploadParts后，会逐一验证每个分片的有效性。当所有的数据分片验证通过后，OSS将把这些分片组合成一个完整的文件。
                 $info  = $ossClient->completeMultipartUpload($this->bucket, $object, $uploadId, $uploadParts);
//                 if ($info['info']['http_code'] == 200) {
//                     return self::sendResult(self::$okCode);
//                 }

                return self::sendResult(self::$okCode);
            }  catch(OssException $e) {
                printf(__FUNCTION__ . ": completeMultipartUpload FAILED\n");
                printf($e->getMessage() . "\n");
                return;
            }

        } catch (\Exception $e) {
            return self::sendResult(128, $e->getMessage());
        }
    }
}